/*
 * Copyright (C) 2012 SeekDeepWithin.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package com.seekdeepwithin.DataAccess;

import java.util.ArrayList;
import com.seekdeepwithin.Data.ReadLink;

/**
 * User: Jonathan Montiverdi
 * Date: Oct 22, 2012
 *
 * Parses a list of passages.
 */
public class Parser
{
    public static ArrayList<ReadLink> Parse (String passages)
    {
        passages = passages.replaceAll ("\\s", "");
        ArrayList<ReadLink> links = new ArrayList<> ();
        String book = "";
        String chapter = "";
        String verse = "";
        boolean isBook = true;
        boolean isChapter = false;
        boolean isVerse = false;
        int charIndex = 0;
        int length = passages.length ();

        while (Character.isDigit (passages.charAt (charIndex)))
        {
            book += passages.charAt (charIndex);
            charIndex++;
        }

        for (; charIndex < length; charIndex++)
        {
            char currentChar = passages.charAt (charIndex);
            if (currentChar == ':')
            {
                isBook = false;
                isChapter = false;
                isVerse = true;
            }
            else if (currentChar == ',')
            {
                boolean handled = false;
                if (isBook)
                {
                    if ((charIndex + 1) < length)
                    {
                        if (!Character.isDigit (passages.charAt (charIndex + 1)))
                        {
                            book += currentChar;
                            handled = true;
                        }
                    }
                }
                if (!handled)
                {
                    AddPassage (links, book, chapter, verse);
                    if (verse.isEmpty ())
                        chapter = "";
                    verse = "";
                }
            }
            else if (currentChar == ';')
            {
                AddPassage (links, book, chapter, verse);
                book = "";
                chapter = "";
                verse = "";
                isBook = true;
                isChapter = false;
                isVerse = false;
            }
            else if (currentChar == '.')
            {
                if (isBook)
                {
                    isBook = false;
                    isChapter = true;
                    isVerse = false;
                }
                else
                {
                    isBook = false;
                    isChapter = false;
                    isVerse = true;
                }
            }
            else if (currentChar == '-')
            {
                if (isChapter)
                    chapter += currentChar;
                else if (isVerse)
                    verse += currentChar;
            }
            else if (Character.isDigit (currentChar))
            {
                if (isBook)
                {
                    if ((charIndex + 1) < length && Character.isLetter (passages.charAt (charIndex + 1)))
                    {
                        book += currentChar;
                    }
                    else
                    {
                        isBook = false;
                        isChapter = true;
                        chapter += currentChar;
                    }
                }
                else if (isChapter)
                {
                    chapter += currentChar;
                }
                else if (isVerse)
                {
                    verse += currentChar;
                }
            }
            else if (isBook)
            {
                book += currentChar;
            }
        }
        AddPassage (links, book, chapter, verse);
        return links;
    }

    private static void AddPassage (ArrayList<ReadLink> links, String book, String chapter, String verse)
    {
        if (book.isEmpty () && chapter.isEmpty ()) return;

        if (book.isEmpty ())
        {
            if (links.size () > 0)
                book = links.get (links.size () - 1).getBook ();
            else
                return;
        }

        String[] bookData = GetBook (book);

        if (bookData [0].isEmpty ())
            return;
        if ("true".equals (bookData [2]) && verse.isEmpty ())
        {
            verse = chapter;
            chapter = "";
        }
        if (verse.contains ("-"))
        {
            String[] split = verse.split ("-");
            int start = Integer.parseInt (split [0]);
            int end = Integer.parseInt (split [1]);
            for (int a = start; a <= end; a++)
            {
                links.add (new ReadLink (bookData [1] + ":" + bookData [0] + ":" + chapter + ":" + a));
            }
        }
        else if (chapter.contains ("-"))
        {
            String[] split = chapter.split ("-");
            int start = Integer.parseInt (split [0]);
            int end = Integer.parseInt (split [1]);
            for (int a = start; a <= end; a++)
            {
                if (!verse.isEmpty () && a == end)
                {
                    int verseInt = Integer.parseInt (verse);
                    for (int b = 1; b <= verseInt; b++)
                    {
                        links.add (new ReadLink (bookData [1] + ":" + bookData [0] + ":" + a + ":" + b));
                    }
                }
                else
                {
                    links.add (new ReadLink (bookData [1] + ":" + bookData [0] + ":" + a + ":"));
                }
            }
        }
        else
            links.add (new ReadLink (bookData [1] + ":" + bookData [0] + ":" + chapter + ":" + verse));
    }

    private static String[] GetBook (String book)
    {
        String b = book.replaceAll ("\\s", "").toLowerCase ();
        String[] bookData = new String[3];
        bookData [1] = "King James Bible";
        bookData [2] = "false";
        switch (b)
        {
            case "":
                bookData [0] = "";
                break;
            case "genesis":
            case "gen":
            case "ge":
            case "gn":
                bookData [0] = "Genesis";
                break;
            case "exodus":
            case "exo":
            case "ex":
            case "exod":
                bookData [0] = "Exodus";
                break;
            case "leviticus":
            case "lev":
            case "le":
            case "lv":
                bookData [0] = "Leviticus";
                break;
            case "numbers":
            case "num":
            case "nu":
            case "nm":
            case "nb":
                bookData [0] = "Numbers";
                break;
            case "deuteronomy":
            case "deut":
            case "dt":
            case "deu":
            case "de":
                bookData [0] = "Deuteronomy";
                break;
            case "joshua":
            case "josh":
            case "jos":
            case "jsh":
                bookData [0] = "Joshua";
                break;
            case "judges":
            case "judg":
            case "jdg":
            case "jg":
            case "jdgs":
                bookData [0] = "Judges";
                break;
            case "ruth":
            case "rth":
            case "ru":
            case "rut":
                bookData [0] = "Ruth";
                break;
            case "1samuel":
            case "1sam":
            case "1sa":
            case "1s":
            case "1sm":
            case "isam":
            case "isamuel":
            case "1stsamuel":
            case "firstsamuel":
                bookData [0] = "1 Samuel";
                break;
            case "2samuel":
            case "2sam":
            case "2sa":
            case "2s":
            case "iisa":
            case "2sm":
            case "iisam":
            case "iisamuel":
            case "2ndsamuel":
            case "secondsamuel":
                bookData [0] = "2 Samuel";
                break;
            case "1kings":
            case "1kgs":
            case "1kg":
            case "1ki":
            case "1k":
            case "ikgs":
            case "iki":
            case "ikings":
            case "1stkgs":
            case "1stkings":
            case "firstkings":
            case "firstkgs":
            case "1kin":
                bookData [0] = "1 Kings";
                break;
            case "2kings":
            case "2kgs":
            case "2kg":
            case "2ki":
            case "2k":
            case "iikgs":
            case "iiki":
            case "iikings":
            case "2ndkgs":
            case "2ndkings":
            case "secondkings":
            case "secondkgs":
            case "2kin":
                bookData [0] = "2 Kings";
                break;
            case "1chronicles":
            case "1chron":
            case "1ch":
            case "ich":
            case "1chr":
            case "ichr":
            case "ichron":
            case "ichronicles":
            case "1stchronicles":
            case "firstchronicles":
                bookData [0] = "1 Chronicles";
                break;
            case "2chronicles":
            case "2chron":
            case "2ch":
            case "iich":
            case "iichr":
            case "2chr":
            case "iichron":
            case "iichronicles":
            case "2ndchronicles":
            case "secondchronicles":
                bookData [0] = "2 Chronicles";
                break;
            case "ezra":
            case "ezr":
                bookData [0] = "Ezra";
                break;
            case "nehemiah":
            case "neh":
            case "ne":
                bookData [0] = "Nehemiah";
                break;
            case "esther":
            case "esth":
            case "es":
                bookData [0] = "Esther";
                break;
            case "job":
            case "jb":
                bookData [0] = "Job";
                break;
            case "psalm":
            case "pslm":
            case "ps":
            case "psalms":
            case "psa":
            case "psm":
            case "pss":
                bookData [0] = "Psalms";
                break;
            case "proverbs":
            case "prov":
            case "pr":
            case "prv":
            case "pro":
                bookData [0] = "Proverbs";
                break;
            case "ecclesiastes":
            case "eccles":
            case "ec":
            case "qoh":
            case "qoheleth":
            case "ecc":
            case "eccl":
                bookData [0] = "Ecclesiastes";
                break;
            case "songofsolomon":
            case "song":
            case "so":
            case "canticleofcanticles":
            case "canticles":
            case "songofsongs":
            case "sos":
                bookData [0] = "Song of Solomon";
                break;
            case "isaiah":
            case "isa":
            case "is":
                bookData [0] = "Isaiah";
                break;
            case "jeremiah":
            case "jer":
            case "je":
            case "jr":
                bookData [0] = "Jeremiah";
                break;
            case "lamentations":
            case "lam":
            case "la":
                bookData [0] = "Lamentations";
                break;
            case "ezekiel":
            case "ezek":
            case "eze":
            case "ezk":
                bookData [0] = "Ezekiel";
                break;
            case "daniel":
            case "dan":
            case "da":
            case "dn":
                bookData [0] = "Daniel";
                break;
            case "hosea":
            case "hos":
            case "ho":
                bookData [0] = "Hosea";
                break;
            case "joel":
            case "joe":
            case "jl":
                bookData [0] = "Joel";
                break;
            case "amos":
            case "am":
            case "amo":
                bookData [0] = "Amos";
                break;
            case "obadiah":
            case "obad":
            case "ob":
            case "obd":
            case "oba":
                bookData [0] = "Obadiah";
                break;
            case "jonah":
            case "jnh":
            case "jon":
                bookData [0] = "Jonah";
                break;
            case "micah":
            case "mic":
                bookData [0] = "Micah";
                break;
            case "nahum":
            case "nah":
            case "na":
                bookData [0] = "Nahum";
                break;
            case "habakkuk":
            case "hab":
                bookData [0] = "Habakkuk";
                break;
            case "zephaniah":
            case "zeph":
            case "zep":
            case "zp":
                bookData [0] = "Zephaniah";
                break;
            case "haggai":
            case "hag":
            case "hg":
                bookData [0] = "Haggai";
                break;
            case "zechariah":
            case "zech":
            case "zec":
            case "zc":
                bookData [0] = "Zechariah";
                break;
            case "malachi":
            case "mal":
            case "ml":
                bookData [0] = "Malachi";
                break;
            case "tobit":
            case "tob":
            case "tb":
                bookData [1] = "Douay-Rheims Bible";
                bookData [0] = "Tobit";
                break;
            case "judith":
            case "jdth":
            case "jdt":
            case "jth":
                bookData [1] = "Douay-Rheims Bible";
                bookData [0] = "Judith";
                break;
            case "additionstoesther":
            case "addesth":
            case "addes":
            case "restofesther":
            case "therestofesther":
            case "aes":
                bookData [0] = "Additions to Esther";
                break;
            case "wisdomofsolomon":
            case "wisdofsol":
            case "wis":
            case "ws":
            case "wisdom":
                bookData [1] = "Douay-Rheims Bible";
                bookData [0] = "Wisdom of Solomon";
                break;
            case "sirach":
            case "sir":
            case "ecclesiasticus":
            case "ecclus":
                bookData [0] = "Sirach";
                break;
            case "baruch":
            case "bar":
                bookData [1] = "Douay-Rheims Bible";
                bookData [0] = "Baruch";
                break;
            case "letterofjeremiah":
            case "letjer":
            case "lje":
            case "ltrjer":
                bookData [0] = "Letter of Jeremiah";
                break;
            case "songofthreeyouths":
            case "songofthree":
            case "songthr":
            case "thesongofthreeyouths":
            case "praz":
            case "prayerofazariah":
            case "azariah":
            case "thesongofthethreeholychildren":
            case "thesongofthreejews":
            case "songofthethreeholychildren":
            case "songofthr":
            case "songofthreechildren":
            case "songofthreejews":
                bookData [0] = "Song of Three Youths";
                break;
            case "susanna":
            case "sus":
                bookData [0] = "Susanna";
                break;
            case "belandthedragon":
            case "bel":
                bookData [0] = "Bel and the Dragon";
                break;
            case "1maccabees":
            case "1macc":
            case "1mac":
            case "1m":
            case "ima":
            case "1ma":
            case "imac":
            case "imacc":
            case "imaccabees":
            case "1stmaccabees":
            case "firstmaccabees":
                bookData [1] = "Douay-Rheims Bible";
                bookData [0] = "1 Maccabees";
                break;
            case "2maccabees":
            case "2macc":
            case "2mac":
            case "2m":
            case "iima":
            case "2ma":
            case "iimac":
            case "iimacc":
            case "iimaccabees":
            case "2ndmaccabees":
            case "secondmaccabees":
                bookData [1] = "Douay-Rheims Bible";
                bookData [0] = "2 Maccabees";
                break;
            case "1esdras":
            case "1esdr":
            case "1esd":
            case "ies":
            case "1es":
            case "iesd":
            case "iesdr":
            case "iesdras":
            case "1stesdras":
            case "firstesdras":
                bookData [0] = "1 Esdras";
                break;
            case "prayerofmanasseh":
            case "profman":
            case "prman":
            case "pma":
            case "prayerofmanasses":
                bookData [0] = "Prayer of Manasseh";
                break;
            case "additionalpsalm":
            case "addpsalm":
            case "addps":
                bookData [0] = "Additional Psalm";
                break;
            case "3maccabees":
            case "3macc":
            case "3mac":
            case "iiima":
            case "3ma":
            case "iiimac":
            case "iiimacc":
            case "iiimaccabees":
            case "3rdmaccabees":
            case "thirdmaccabees":
                bookData [0] = "3 Maccabees";
                break;
            case "2esdras":
            case "2esdr":
            case "2esd":
            case "iies":
            case "2es":
            case "iiesd":
            case "iiesdr":
            case "iiesdras":
            case "2ndesdras":
            case "secondesdras":
                bookData [0] = "2 Esdras";
                break;
            case "4maccabees":
            case "4macc":
            case "4mac":
            case "ivma":
            case "4ma":
            case "ivmac":
            case "ivmacc":
            case "ivmaccabees":
            case "iiiimaccabees":
            case "4thmaccabees":
            case "fourthmaccabees":
                bookData [0] = "4 Maccabees";
                break;
            case "ode":
                bookData [0] = "Ode";
                break;
            case "psalmsofsolomon":
            case "pssolomon":
            case "pssol":
            case "psalmssolomon":
                bookData [0] = "Psalms of Solomon";
                break;
            case "epistletothelaodiceans":
            case "laodiceans":
            case "laod":
            case "eplaod":
            case "epistlaodiceans":
            case "epistlelaodiceans":
            case "epistletolaodiceans":
                bookData [0] = "Epistle to the Laodiceans";
                break;
            case "matthew":
            case "matt":
            case "mt":
            case "mat":
                bookData [0] = "Matthew";
                break;
            case "mark":
            case "mrk":
            case "mk":
            case "mr":
                bookData [0] = "Mark";
                break;
            case "luke":
            case "luk":
            case "lk":
            case "lu":
                bookData [0] = "Luke";
                break;
            case "john":
            case "jn":
            case "jhn":
            case "joh":
                bookData [0] = "John";
                break;
            case "acts":
            case "ac":
            case "act":
                bookData [0] = "Acts";
                break;
            case "romans":
            case "rom":
            case "ro":
            case "rm":
                bookData [0] = "Romans";
                break;
            case "1corinthians":
            case "1cor":
            case "1co":
            case "ico":
            case "icor":
            case "icorinthians":
            case "1stcorinthians":
            case "firstcorinthians":
                bookData [0] = "1 Corinthians";
                break;
            case "2corinthians":
            case "2cor":
            case "2co":
            case "iico":
            case "iicor":
            case "iicorinthians":
            case "2ndcorinthians":
            case "secondcorinthians":
                bookData [0] = "2 Corinthians";
                break;
            case "galatians":
            case "gal":
            case "ga":
                bookData [0] = "Galatians";
                break;
            case "ephesians":
            case "ephes":
            case "eph":
                bookData [0] = "Ephesians";
                break;
            case "philippians":
            case "phil":
            case "php":
            case "phili":
            case "philip":
                bookData [0] = "Philippians";
                break;
            case "colossians":
            case "col":
                bookData [0] = "Colossians";
                break;
            case "1thessalonians":
            case "1thess":
            case "1th":
            case "ith":
            case "ithes":
            case "1thes":
            case "ithess":
            case "ithessalonians":
            case "1stthessalonians":
            case "firstthessalonians":
                bookData [0] = "1 Thessalonians";
                break;
            case "2thessalonians":
            case "2thess":
            case "2th":
            case "iith":
            case "iithes":
            case "2thes":
            case "iithess":
            case "iithessalonians":
            case "2ndthessalonians":
            case "secondthessalonians":
                bookData [0] = "2 Thessalonians";
                break;
            case "1timothy":
            case "1tim":
            case "1ti":
            case "iti":
            case "itim":
            case "itimothy":
            case "1sttimothy":
            case "firsttimothy":
                bookData [0] = "1 Timothy";
                break;
            case "2timothy":
            case "2tim":
            case "2ti":
            case "iiti":
            case "iitim":
            case "iitimothy":
            case "2ndtimothy":
            case "secondtimothy":
                bookData [0] = "2 Timothy";
                break;
            case "titus":
            case "tit":
                bookData [0] = "Titus";
                break;
            case "philemon":
            case "philem":
            case "phm":
                bookData [0] = "Philemon";
                break;
            case "hebrews":
            case "heb":
                bookData [0] = "Hebrews";
                break;
            case "james":
            case "jas":
            case "jm":
            case "jam":
                bookData [0] = "James";
                break;
            case "1peter":
            case "1pet":
            case "1pe":
            case "ipe":
            case "ipet":
            case "ipt":
            case "1pt":
            case "ipeter":
            case "1stpeter":
            case "firstpeter":
                bookData [0] = "1 Peter";
                break;
            case "2peter":
            case "2pet":
            case "2pe":
            case "iipe":
            case "iipet":
            case "iipt":
            case "2pt":
            case "iipeter":
            case "2ndpeter":
            case "secondpeter":
                bookData [0] = "2 Peter";
                break;
            case "1john":
            case "1jn":
            case "ijn":
            case "ijo":
            case "1jo":
            case "ijoh":
            case "1joh":
            case "ijhn":
            case "1jhn":
            case "ijohn":
            case "1stjohn":
            case "firstjohn":
                bookData [0] = "1 John";
                break;
            case "2john":
            case "2jn":
            case "iijn":
            case "iijo":
            case "2jo":
            case "iijoh":
            case "2joh":
            case "iijhn":
            case "2jhn":
            case "iijohn":
            case "2ndjohn":
            case "secondjohn":
                bookData [0] = "2 John";
                break;
            case "3john":
            case "3jn":
            case "iiijn":
            case "iiijo":
            case "3jo":
            case "iiijoh":
            case "3joh":
            case "iiijhn":
            case "3jhn":
            case "iiijohn":
            case "3rdjohn":
            case "thirdjohn":
                bookData [0] = "3 John";
                break;
            case "jude":
            case "jud":
                bookData [0] = "Jude";
                break;
            case "revelation":
            case "rev":
            case "re":
            case "therevelation":
                bookData [0] = "Revelation";
                break;
            case "aquariangospelofjesusthechrist":
            case "agjc":
                bookData [1] = "Passage";
                bookData [0] = "Aquarian Gospel of Jesus the Christ";
                break;
            case "gospelofbuddha":
            case "gob":
                bookData [1] = "Passage";
                bookData [0] = "Gospel of Buddha";
                break;
            case "bhagavadgita":
            case "bg":
                bookData [1] = "Passage";
                bookData [0] = "Bhagavad Gita";
                break;
            case "thelifeofsaintissa":
            case "lifeofsaintissa":
            case "lsi":
            case "lsibsm":
                bookData [1] = "Passage";
                bookData [0] = "The Life of Saint Issa";
                break;
            case "thegospelofpeter":
            case "gospelofpeter":
            case "gop":
                bookData [2] = "true";
                bookData [1] = "Passage";
                bookData [0] = "Gospel of Peter";
                break;
            default:
                bookData [0] = "";
                break;
        }
        return bookData;
    }
}
